package com.hd.until;

//import com.google.common.base.Strings;

public class BankCardTest {
	
	private static int i = 0;
	
	/**
	 * 需要传入一个前缀：6、8、9中的一个。
	 * 其中：6：类型1，8：类型2，9：类型3 【根据自己的业务定义】
	 * 其他则会返回异常
	 */
	public synchronized static String getBrankNumber(String prefix) {
		if(!"".equals(prefix)&& null!=prefix){
			if("689".indexOf(prefix)>=0&&prefix.length()==1){
//				String st = "621483013470869"; //  + prefix+getUnixTime();
				String st = "62148565" +getUnixTime(); //招行 
//				String st = "62276098" +getUnixTime();  //中行
//				String st = "62261521" +getUnixTime();  //民生
//				String st = "62226237" +getUnixTime();  //交通
//				String st = "60296920" +getUnixTime();  //北京
//				String st = "62246800" +getUnixTime();  //上海
				return st+getBankCardCheckCode(st);
				
			}else{
				System.out.println("银行卡号前缀有误");
			}
			
		}else{
			System.out.println("银行卡号去前缀不能是空");
		}
		
		return "";
	}
	
	/***
	 * 获取当前系统时间戳 并截取 
	 * @return
	 */
	private synchronized static String getUnixTime(){
		try {
			Thread.sleep(10);//线程同步执行，休眠10毫秒 防止卡号重复
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		i++;
		i = i > 100 ? i % 10 : i;
		return ( (System.currentTimeMillis() / 100 ) + "").substring(5) + (i % 10);
	}
	
	/**
     * 校验银行卡卡号
     * @param cardId
     * @return
     */
    public static boolean checkBankCard(String cardId) {
         char bit = getBankCardCheckCode(cardId.substring(0, cardId.length() - 1));
         if(bit == 'N'){
             return false;
         }
         return cardId.charAt(cardId.length() - 1) == bit;
    }
    
    /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     * @param nonCheckCodeCardId
     * @return
     */
    public static char getBankCardCheckCode(String nonCheckCodeCardId){
        if(nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0
                || !nonCheckCodeCardId.matches("\\d+")) {
            //如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardId.trim().toCharArray();
        int luhmSum = 0;
        for(int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if(j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;           
        }
        return (luhmSum % 10 == 0) ? '0' : (char)((10 - luhmSum % 10) + '0');
    }
    
    /** 
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位 
     * 该校验的过程：  
     * 1、从卡号最后一位数字开始，逆向将奇数位(1、3、5等等)相加。  
     * 2、从卡号最后一位数字开始，逆向将偶数位数字，先乘以2（如果乘积为两位数，则将其减去9），再求和。  
     * 3、将奇数位总和加上偶数位总和，结果应该可以被10整除。 
     */
    static char getBankCardCheckCode0(String nonCheckCodeCardId) {
        if (nonCheckCodeCardId == null || nonCheckCodeCardId.trim().length() == 0
                || !nonCheckCodeCardId.matches("\\d+") || nonCheckCodeCardId.trim().length() < 15
                || nonCheckCodeCardId.trim().length() > 18) {
            // 如果传的数据不合法返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardId.trim().toCharArray();
        int luhmSum = 0;
        // 执行luh算法
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) { // 偶数位处理
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }
    
    public static void main(String[] args) {
//    	System.out.println(getUnixTime());
//    	System.out.println(((System.currentTimeMillis() / 100 ) + "").substring(4));
//    	System.out.println(checkBankCard("6226220666043616"));
    	try {
    		for(int i = 0;i<100 ;i++){
    		System.out.println(getBrankNumber("6"));    				
//			System.out.println(getUnixTime());
//    		System.out.println(getBankCardCheckCode0("621483013470536"));
//			System.out.println(getBankCardCheckCode0("622622330091297"));
//			System.out.println(checkBankCard(getBrankNumber("6")));
//			System.out.println("=============");
    		}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
